package com.eci.common.util;

import java.io.IOException;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;

import com.eci.common.asset.constant.ObjectConstant.DatexFormatter;
import com.eci.common.asset.constant.StringConstant.Json;
import com.eci.common.asset.custom.CustomDateDeserializer;
import com.eci.common.asset.custom.CustomDateSerializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
 

public enum JacksonUtil {

	i;

	private ObjectMapper mapper;
	private TypeReference<Map<String, Object>> mapType = new TypeReference<Map<String, Object>>() {} ;
	private TypeReference<List<Map<String, Object>>> listmType = new TypeReference<List<Map<String, Object>>>() {};

	static {
		
		i.mapper = new ObjectMapper();
		i.mapper.setTimeZone(DatexFormatter.TIME_ZONE_E8);
		i.mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); // 对于空的对象转json的时候不抛出错误
		i.mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 禁用遇到未知属性抛出异常
		i.mapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);// 序列化BigDecimal时不使用科学计数法输出  
		i.mapper.registerModule(sqltimeModule()); 
		i.mapper.registerModule(localtimeModule());
		
	}
	
	
	private  static SimpleModule sqltimeModule() {
		
		SimpleModule sqltimeModule = new SimpleModule();
		
		sqltimeModule.addSerializer(Timestamp.class, new CustomDateSerializer.TimestampSerializer());
		sqltimeModule.addSerializer(Date.class, new CustomDateSerializer.SqlDateSerializer());
		sqltimeModule.addSerializer(Time.class, new CustomDateSerializer.SqlTimeSerializer());
		sqltimeModule.addDeserializer(Timestamp.class, new CustomDateDeserializer.TimestampDeserializer());
		sqltimeModule.addDeserializer(Date.class, new CustomDateDeserializer.SqlDateDeserializer());
		sqltimeModule.addDeserializer(Time.class, new CustomDateDeserializer.SqlTimeDeserializer());
		
		return sqltimeModule;
	}
	
	private static JavaTimeModule localtimeModule() {
		
		JavaTimeModule localtimeModule = new JavaTimeModule();
		
		LocalDateTimeSerializer datimeSlizer = new LocalDateTimeSerializer(DatexFormatter.STANDARD_DATETIME);
		LocalDateSerializer dateSlizer = new LocalDateSerializer(DatexFormatter.STANDARD_DATE);
		LocalTimeSerializer timeSlizer = new LocalTimeSerializer(DatexFormatter.STANDARD_TIME);
		LocalDateTimeDeserializer datimeDlizer = new LocalDateTimeDeserializer(DatexFormatter.STANDARD_DATETIME);
		LocalDateDeserializer dateDlizer = new LocalDateDeserializer(DatexFormatter.STANDARD_DATE);
		LocalTimeDeserializer timeDlizer = new LocalTimeDeserializer(DatexFormatter.STANDARD_TIME);
		
		localtimeModule.addSerializer(LocalDateTime.class, datimeSlizer);
		localtimeModule.addSerializer(LocalDate.class, dateSlizer);
		localtimeModule.addSerializer(LocalTime.class, timeSlizer);
		localtimeModule.addDeserializer(LocalDateTime.class, datimeDlizer);
		localtimeModule.addDeserializer(LocalDate.class, dateDlizer);
		localtimeModule.addDeserializer(LocalTime.class, timeDlizer);
		
		return localtimeModule;
	}

	/**
	 * 	创建一个JSON对象
	 */
	public static ObjectNode createObjectNode() {

		return i.mapper.createObjectNode();
	}

	/**
	 * 	创建一个JSON数组
	 */
	public static ArrayNode createArrayNode() {

		return i.mapper.createArrayNode();
	}

	/**
	 *	 判断一个字符串是否是合法的json格式字符串
	 * 
	 */

	public static boolean isJson(String jsonStr) {

		try {
			i.mapper.readTree(jsonStr);
			return true;
		} catch (JsonProcessingException e) {
			return false;
		}

	}

	/**
	 * 	字符串转Json对象
	 * 
	 */
	public static ObjectNode readJsonObject(String jsonStr) {
		JsonNode node = null;
		ObjectNode objNode = null;
		try {
			node = i.mapper.readTree(jsonStr);
			if (!node.isArray()) {
				objNode = (ObjectNode) node;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return objNode;

	}

	/**
	 * 	字符串转Json数组
	 */
	public static ArrayNode readJsonArray(String jsonStr) {

		JsonNode node = null;
		ArrayNode arrNode = null;
		try {
			node = i.mapper.readTree(jsonStr);
			if (node.isArray()) {
				arrNode = (ArrayNode) node;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return arrNode;

	}
	
	
	/**
	 * 	字符串转JsonNode
	 */
	public static JsonNode readJson(String jsonStr) {
		try {
			return i.mapper.readTree(jsonStr);
		} catch (IOException e) {
			
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 	字节数组转JSON
	 */
	public static JsonNode readJson(byte[] content) {
		try {
			return i.mapper.readTree(content);
		} catch (IOException e) {
			
			e.printStackTrace();
			return null;
		}
	}
	
	

	/**
	 *	 将JSON对象转成Map
	 * 
	 * @param objectNode   json非数组对象
	 * @return Map
	 */
	public static Map<String, Object> jsonObjct2Map(ObjectNode objectNode) {

		return i.mapper.convertValue(objectNode, i.mapType);
	}

	/**
	 * 	将JSON对象转成类型
	 * 
	 * @param objectNode json非数组对象
	 * @return Map
	 */
	public static <T> T jsonObjct2Object(ObjectNode objectNode, Class<T> toType) {

		return i.mapper.convertValue(objectNode, toType);
	}

	/**
	 * 	将JSON对象转成List&ltMap>
	 * 
	 * @param arryNode  json数组对象
	 * @return List
	 */
	public static List<Map<String, Object>> jsonArray2List(ArrayNode arryNode) {

		return i.mapper.convertValue(arryNode, i.listmType);
	}

	/**
	 * 	将JsonNode转成指定类型的
	 * 
	 * @param jsonNode
	 * @return T
	 */
	public static <T> T jsonNode2Type(JsonNode jsonNode, TypeReference<T> typeReference) {

		return i.mapper.convertValue(jsonNode, typeReference);

	}

	/**
	 * 	将字符串转成指定class类型对象
	 */
	public static <T> T readJson(String jsonStr, Class<T> T) {
		T obj = null;
		try {
			obj = i.mapper.readValue(jsonStr, T);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 	将字符串转成指定类型的对象
	 */
	public static <T> T readJson(String jsonStr, TypeReference<T> typeReference) {
		T obj = null;
		try {
			obj = i.mapper.readValue(jsonStr, typeReference);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 	将java对象转成字符串
	 */
	public static String writeJson(Object entity) {
		String str = Json.EMPTY_OBJECT;
		if (entity == null) {
			return str;
		}

		try {
			str = i.mapper.writeValueAsString(entity);
		} catch (JsonProcessingException e) {

			e.printStackTrace();
		}
		return str;
	}

	/**
	 *	 将对象实体转换成Jackson的ObjectNode
	 */
	public static ObjectNode bean2ObjNode(Object bean) {
		
		return i.mapper.convertValue(bean, ObjectNode.class);
	}
	
	
	
	/**  将对象转换成JsonNode  */
	public static JsonNode convertToJsonNode (Object object) {
		  
		return i.mapper.valueToTree(object);
	}
	 
	
	/**  将Map转换成JsonNode  */
	public static JsonNode convertToJsonNode(Map<String,Object> map) {
		  
		return i.mapper.convertValue(map, JsonNode.class);
	}
	
}
